assume cs:code,ds:data

data segment
	char_stack	db 100 dup (0) ;字符栈
	top dw 0 ;字符栈栈顶索引
	fun_table dw char_push, char_pop, show_strs
data ends


code segment
start:				
					;设置ds和si
					mov ax, data
					mov ds, ax
					mov si, offset char_stack
					;mov ax, offset start_read ;offset是相对于本段的偏移，此处offset start_read的值为0Bh(十进制的11)
					;mov ax, offset top ;offset是相对于本段的偏移，此处offset top为64h(十进制的100)

start_read:			mov ah, 0
					int 16h ;从BIOS键盘缓冲区中读取内容,ah中放扫描码，al中放对应的ascii码
					cmp al, 20h
					jb	not_char

					;调用str_operate完成字符s入栈
					mov ah, 0 ;str_operate入栈的功能号为0
					call str_operate

					;显示字符串
					mov ah, 2
					mov dh, 12 ;行
					mov dl, 40 ;列
					call str_operate

					;继续读取BIOS键盘缓冲区
					jmp short start_read


;非字符
not_char:			cmp ah, 0eh ;Backspace键		
					je 	back_space
					cmp ah, 1ch ;Enter键
					je enter_my
					;继续读取BIOS键盘缓冲区
					jmp short start_read


;返回键
back_space:			mov ah, 1
					call str_operate
					;显示字符串
					mov ah, 2
					mov dh, 12 ;行
					mov dl, 40 ;列
					call str_operate
					;继续读取BIOS键盘缓冲区
					jmp short start_read



;Enter键
enter_my:			;把0入栈
					mov ah, 0
					mov al, 0
					call str_operate
					;显示字符串
					mov ah, 2
					mov dh, 12 ;行
					mov dl, 40 ;列
					call str_operate
					jmp short exit_my


exit_my:			mov ax, 4c00h
					int 21h


;字符串入栈，出栈，显示
;ah功能号，0表示入栈，1表示出栈，2表示显示
;ds:si指向字符栈空间
;对于入栈，al = 入栈字符
;对于出栈，al = 出栈字符
;对于显示，dh dl分别存储行列
str_operate:		push bx
					push es
					push ax
					push di

					;验证功能号，根据功能号跳到不同的地方执行
					cmp ah, 0
					jb str_operate_end
					cmp ah, 2
					ja str_operate_end
					mov bl, ah
					mov bh, 0
					add bx, bx
					jmp word ptr fun_table[bx] ;


;入栈
char_push:			mov bx, top
					mov ds:[si + bx], al
					inc bx
					mov top, bx ;修改索引
					jmp short str_operate_end
			
;出栈
char_pop:			mov bx, top
					cmp bx, 0
					jna str_operate_end ;索引小于等于0，直接结束
					dec bx
					mov al, ds:[si + bx]
					mov byte ptr ds:[si + bx], ' ' ;删除的地方设置成空格，否则显示会有问题
					mov top, bx
					jmp short str_operate_end


;显示字符串
show_strs:			mov bx, top
					cmp bx, 0
					jna str_operate_end	
					mov bx, 0b800h	
					mov es, bx	
					mov al, 160
					mov ah, 0
					mul dh ;160乘以行
					mov dh, 0
					add dx, dx ;列乘以2
					add ax, dx ;输出的位置,行加列	
					mov di, ax

					mov bx, 0
show_strs_s0:		cmp bx, top
					je str_operate_end
					mov al, ds:[si + bx]
					mov es:[di], al
					mov byte ptr es:[di + 1], 42h
					inc bx
					add di, 2
					jmp short show_strs_s0

	
str_operate_end:	pop di
					pop ax
					pop es
					pop bx
					ret

code ends


end start